<?php
namespace App\Services;

use App\MenuPermission;
use App\RoleMenuPermission;
use App\BaseDictionary;
use App\Lib\Util\QueryPager;

class MenuPermissionService
{
    public function createMenuPermission($menuPermission)
    {
        return MenuPermission::create($menuPermission);
    }

    public function getNaviMenuPermissions(Array $input)
    {
        return $this->getMenuPermissions($input, [
            MenuPermission::$PERMISSION_TYPE_TOP_NAVI
        ]);
    }

    public function getApiPermissions(Array $input)
    {
        return $this->getMenuPermissions($input, [
            MenuPermission::$PERMISSION_TYPE_API
        ]);
    }

    public function getDefaultMenuPermission()
    {
        return MenuPermission::where('is_default', BaseDictionary::$KEY_YES)->first();
    }

    public function getCascadeMenuPermissionByLevel($level, $spread = true)
    {
        $topNavi = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
            ->where('permission_type', MenuPermission::$PERMISSION_TYPE_TOP_NAVI)
            ->orderBy('sort_order')->get()->toArray();

        $result = [];

        foreach ($topNavi as $topNaviItem) {
            $menuGroups = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
                ->where('permission_type', MenuPermission::$PERMISSION_TYPE_MENU_GROUP)
                ->where('parent_id', $topNaviItem['id'])
                ->orderBy('sort_order')->get()->toArray();

            $childrenLevel1 = [];

            if ($level > 1) {
                foreach ($menuGroups as $menuGroup) {
                    $menus = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
                        ->where('permission_type', MenuPermission::$PERMISSION_TYPE_MENU)
                        ->where('parent_id', $menuGroup['id'])
                        ->orderBy('sort_order')->get()->toArray();

                    $childrenLevel2 = [];

                    if ($level > 2) {
                        if ($level > 3) {
                            foreach ($menus as $menu) {
                                $permissions = MenuPermission::select('id', 'name', 'permission_type', 'is_default')
                                    ->where('permission_type', MenuPermission::$PERMISSION_TYPE_OPERATION)
                                    ->where('parent_id', $menu['id'])
                                    ->orderBy('sort_order')->get()->toArray();

                                array_push($childrenLevel2, array_merge($menu, [
                                    'spread' => $spread,
                                    'children' => $permissions
                                ]));
                            }
                        } else {
                            $childrenLevel2 = $menus;
                        }
                    }

                    array_push($childrenLevel1, array_merge($menuGroup, [
                        'spread' => $spread,
                        'children' => $childrenLevel2
                    ]));
                }
            }

            array_push($result, array_merge($topNaviItem, [
                'spread' => $spread,
                'children' => $childrenLevel1
            ]));
        }

        return $result;
    }

    public function getMenuPermissions(Array $input, Array $menuTypes, $paging = true)
    {
        $query = $this->baseQuery($menuTypes);

        if(!empty($input['permissionName'])){
            $query = $query->where('name', 'like', "%".$input['permissionName']."%");
        }

        if(!empty($input['parentId'])){
            $query = $query->where('parent_id', $input['parentId']);
        } else if (isset($input['parentId'])) {
            if ($input['parentId'] === '') {
                $query = $query->whereNull('parent_id');
            }
        }

        if(!empty($input['permissionType'])){
            $query = $query->where('permission_type', $input['permissionType']);
        }

        $pager = new QueryPager($query);

        $pager->mapField('permission_type', MenuPermission::$PERMISSION_TYPE_MAP);
        $pager->mapField('is_default', MenuPermission::$IS_DEFAULT_MAP);

        return $paging ? $this->formatResult($pager->doPaginate($input, 'sort_order')) :
            $this->formatResult($pager->queryWithoutPaginate($input, 'sort_order'));
    }

    private function formatResult($originResult)
    {
        $isInPaging = array_key_exists('list', $originResult);
        if ($isInPaging) {
            $dataList = $originResult['list'];
        } else {
            $dataList = $originResult;
        }

        $formatted = [];

        foreach ($dataList as $item) {
            $item['icon'] = htmlspecialchars_decode($item['icon']);
            array_push($formatted, $item);
        }

        if ($isInPaging) {
            $originResult['list'] = $formatted;
        } else {
            $originResult = $formatted;
        }

        return $originResult;
    }

    private function baseQuery(Array $menuTypes)
    {
        return MenuPermission::with('route', 'parent')
            ->whereIn('permission_type', $menuTypes);
    }

    public function hasChildren($permissionId)
    {
        return MenuPermission::where('parent_id', $permissionId)->count() > 0;
    }

    public function hasConstrait($permissionId)
    {
        return RoleMenuPermission::where('permission_id', $permissionId)->count() > 0;
    }
}
